#!coding:utf-8
# vim: tabstop=4 shiftwidth=4 softtabstop=4
"""
    Singleton connection
    Jay.Han
"""
from libvirt import libvirtError

CVIRT_CONNECTION = None
libvirt = None
import logging
from cvirt.common import config

conf = config.load_settings()
conn_cache = {}

LOG = logging.getLogger("libvirt.connection")
#libvirt connection pool
def get_connection(uri=None,cache=True):
    uri = uri or conf['hypervisor_uri']
    global libvirt
    if libvirt is None:
        libvirt = __import__('libvirt')

    if cache and conn_cache.has_key(uri):
        conn = conn_cache[uri]
        if conn.isAlive():
            # LOG.debug("find alive connection with uri:%s" % uri)
            return connection_wrap(conn,uri)

    auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
            'root',
            None]
    conn = libvirt.openAuth(uri, auth, 0)
    conn_cache[uri] = conn
    return connection_wrap(conn,uri)

class connection_wrap(object):
    def __init__(self,conn,uri):
        self.conn = conn
        self.uri = uri

    def __getattr__(self, item):
        if hasattr(self.conn,item):
            return self._wrap_call(getattr(self.conn,item))

    def _wrap_call(self,func):
        def _inner(*args,**kwargs):
            try:
                return func(*args,**kwargs)
            except libvirtError as e:
                if conn_cache.has_key(self.uri):
                    del conn_cache[self.uri]
                raise
        return _inner


def get_single_conn():
    global CVIRT_CONNECTION

    if CVIRT_CONNECTION is None:
        CVIRT_CONNECTION = get_connection()
    return CVIRT_CONNECTION

conn = get_single_conn()